高效更新

您所在的位置:网站首页 EntityFramework plus 高效更新

高效更新

2023-06-25 08:05| 来源: 网络整理| 查看: 265

高效更新 项目 05/09/2023 批处理

EF Core 通过在一次往返中自动将所有更新批处理在一起,帮助最大限度地减少往返。 考虑以下情况:

var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com"); blog.Url = "http://someotherblog.microsoft.com"; context.Add(new Blog { Url = "http://newblog1.microsoft.com" }); context.Add(new Blog { Url = "http://newblog2.microsoft.com" }); context.SaveChanges();

上述操作从数据库加载博客,更改其 URL,然后添加两个新博客;若要应用此更改,将两个 SQL INSERT 语句和一个 UPDATE 语句发送到数据库。 EF Core 在内部跟踪这些更改,并在调用 时在单个往返中执行这些更改,而不是在添加 Blog 实例时 SaveChanges 逐个发送这些更改。

EF 在一次往返中批处理的语句数量取决于所使用的数据库提供程序。 例如,性能分析表明,当涉及的语句少于 4 个时,批处理对于 SQL Server 的效率通常较低。 同样,对于 SQL Server,批处理的优势在大约 40 条语句后会降低,因此 EF Core 默认在单个批处理中最多只执行 42 条语句,并在单独的往返中执行额外的语句。

用户也可以调整这些阈值以获得潜在的更高性能,但是在修改这些阈值之前要仔细地进行基准测试:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer( @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True", o => o .MinBatchSize(1) .MaxBatchSize(100)); } 相关时使用 ExecuteUpdate 和 ExecuteDelete

假设你想给所有员工加薪。 EF Core 中对此的典型实现如下所示:

foreach (var employee in context.Employees) { employee.Salary += 1000; } context.SaveChanges();

虽然这是完全有效的代码,但是让我们从性能的角度来分析一下它的作用:

执行一次数据库往返,以加载所有相关员工;请注意,这会将员工的所有行数据带到客户端(即使只需要工资数据)。 EF Core 的更改跟踪在加载实体时创建快照,然后将这些快照与实例进行比较,找出哪些属性发生了更改。 通常,执行第二次数据库往返以保存所有更改 (请注意,某些数据库提供程序) 将更改拆分为倍数往返。 尽管这种批处理行为远好于每次更新的往返,但 EF Core 仍按员工发送 UPDATE 语句,数据库必须单独执行每个语句。

从 EF Core 7.0 开始,可以使用 ExecuteUpdate 和 ExecuteDelete 方法来更高效地执行相同操作:

context.Employees.ExecuteUpdate(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));

这会将以下 SQL 语句发送到数据库:

UPDATE [Employees] SET [Salary] = [Salary] + 1000;

这 UPDATE 在一次往返中执行整个操作,无需加载或将任何实际数据发送到数据库,也无需使用 EF 的更改跟踪机制,这会产生额外的开销。 有关详细信息,请参阅 ExecuteUpdate 和 ExecuteDelete。

如果使用的是尚不支持 ExecuteUpdate 和 ExecuteDelete的旧版 EF Core,或者想要执行这些方法不支持的复杂 SQL 语句,则仍可使用 SQL 查询执行操作:

EF Core 7.0 旧版本 context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000"); context.Database.ExecuteSqlInterpolated($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");

若要详细了解 和ExecuteDeleteExecuteUpdate/ 之间的差异SaveChanges,请参阅有关保存数据的概述页。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3